﻿#include "networktool.h"
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include "jsontool.h"
#include <QNetworkConfiguration>
#include <QNetworkReply>
#include <QEventLoop>
#include <QTextCodec>
NetworkTool::NetworkTool()
{
    m_timeout = 10000;
}

bool NetworkTool::sendGet(QString url, QString headerJson, int timeout, QString& rtn, QString &msg)
{
    QNetworkAccessManager qnam;
    const QUrl aurl(url);
    QNetworkRequest qnr(aurl);
    if (timeout == -1) {
        qnr.setTransferTimeout(m_timeout);
    } else {
        qnr.setTransferTimeout(timeout);
    }
    if(!headerJson.isEmpty())
    {
        // 解析 JSON 字符串为 QJsonObject
        QJsonDocument jsonDoc = QJsonDocument::fromJson(headerJson.toUtf8());
        if (jsonDoc.isObject()) {
            QJsonObject jsonObject = jsonDoc.object();

            // 遍历 JSON 对象的键值对，并设置为 HTTP 请求的 Header
            for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
                QString key = it.key();
                QString value = it.value().toString();
                qnr.setRawHeader(key.toUtf8(), value.toUtf8());
            }
        }
    }


    QSslConfiguration config;
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    config.setProtocol(QSsl::TlsV1_0OrLater);
    qnr.setSslConfiguration(config);

    QNetworkConfiguration configTime = qnam.configuration();
    if (timeout == -1) {
        configTime.setConnectTimeout(m_timeout);
    } else {
        configTime.setConnectTimeout(timeout);
    }
    qnam.setConfiguration(configTime);

    QNetworkReply *reply = nullptr;
    try {
        reply = qnam.get(qnr);
        reply->setSslConfiguration(config);

        QEventLoop eventloop;
        connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
        eventloop.exec(QEventLoop::ExcludeUserInputEvents);

        if (reply->error() != QNetworkReply::NoError) {
            msg = QStringLiteral("Network request failed: ") + reply->errorString();
            return false;
        }

        QTextCodec *codec = QTextCodec::codecForName("utf8");
        QString replyData = codec->toUnicode(reply->readAll());
        rtn = replyData;

        reply->deleteLater();
        reply = nullptr;
        //qInfo() << "sendGet,url:" << url << ",return：" << replyData;

            return true;
    } catch (const std::exception &e) {
        // 捕获 C++ 异常
        msg = QStringLiteral("Caught exception: ") + e.what();
    } catch (...) {
        // 捕获其他异常
        msg = QStringLiteral("Caught an unknown exception.");
    }

    if (reply) {
        reply->deleteLater();
    }

    return false;
}

bool NetworkTool::sendPost(QString url, QString headerJson, QString paramJson, int timeout, QString& rtn, QString &msg)
{
    QNetworkAccessManager qnam;
    const QUrl aurl(url);
    QNetworkRequest qnr(aurl);
    if (timeout == -1) {
        qnr.setTransferTimeout(m_timeout);
    } else {
        qnr.setTransferTimeout(timeout);
    }

    qnr.setRawHeader("Content-Type", "application/json");

    if(!headerJson.isEmpty())
    {
        // 解析 JSON 字符串为 QJsonObject
        QJsonDocument jsonDoc = QJsonDocument::fromJson(headerJson.toUtf8());
        if (jsonDoc.isObject()) {
            QJsonObject jsonObject = jsonDoc.object();

            // 遍历 JSON 对象的键值对，并设置为 HTTP 请求的 Header
            for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
                QString key = it.key();
                QString value = it.value().toString();
                qnr.setRawHeader(key.toUtf8(), value.toUtf8());
            }
        }
    }

    QSslConfiguration config;
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    config.setProtocol(QSsl::TlsV1_0OrLater);
    qnr.setSslConfiguration(config);

    QNetworkConfiguration configTime = qnam.configuration();
    if (timeout == -1) {
        configTime.setConnectTimeout(m_timeout);
    } else {
        configTime.setConnectTimeout(timeout);
    }
    qnam.setConfiguration(configTime);

    QNetworkReply *reply = nullptr;
    try {
        reply = qnam.post(qnr, paramJson.toLocal8Bit());
        reply->setSslConfiguration(config);

        QEventLoop eventloop;
        connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
        eventloop.exec(QEventLoop::ExcludeUserInputEvents);

        if (reply->error() != QNetworkReply::NoError) {
            msg = QStringLiteral("Network request failed: ") + reply->errorString();
            return false;
        }

        QTextCodec *codec = QTextCodec::codecForName("utf8");
        QString replyData = codec->toUnicode(reply->readAll());
        rtn = replyData;

        reply->deleteLater();
        reply = nullptr;
        //qInfo() << "sendPost,url:" << url << ",return：" << replyData;

        return true;
    } catch (const std::exception &e) {
        // 捕获 C++ 异常
        msg = QStringLiteral("Caught exception: ") + e.what();
    } catch (...) {
        // 捕获其他异常
        msg = QStringLiteral("Caught an unknown exception.");
    }

    if (reply) {
        reply->deleteLater();
    }

    return false;
}

bool NetworkTool::setTimeOut(int timeout)
{
    m_timeout = timeout;
    return true;
}
